package com.hodge.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hodge.core.enums.ResultCode;
import com.hodge.web.dao.UserInfoDao;
import com.hodge.web.entity.TabRole;
import com.hodge.web.entity.TabUser;
import com.hodge.web.entity.UserRole;
import com.hodge.web.entity.UserVO;
import com.hodge.web.service.RoleService;
import com.hodge.web.service.UserInfoService;
import com.hodge.web.service.UserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 用户信息(UserInfo)表服务实现类
 *
 * @author haojun
 * @since 2020-03-15 12:54:21
 */
@CacheConfig(cacheNames = "userCache")
@Service("userInfoService")
public class UserInfoServiceImpl extends ServiceImpl<UserInfoDao, TabUser> implements UserInfoService {

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleService roleService;

    @Override
    public boolean save(TabUser entity) {
        Optional.ofNullable(getByUsername(entity.getUsername()))
                .ifPresent(info -> {
                    throw ResultCode.EXIST_ACCOUNT.toException();
                });
        return super.save(entity);
    }

    @Override
    public Optional<TabUser> getByUsername(String username) {
        QueryWrapper<TabUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        return Optional.ofNullable(this.getOne(wrapper));
    }

    @Override
    public UserVO getCurrent() {
        return (UserVO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    }

    @Cacheable(key = "#id")
    @Override
    public UserVO getDetails(Long id) {
        UserVO userVO = getById(id).toUserVO();
        QueryWrapper<UserRole> queryUserRole = new QueryWrapper<>();
        queryUserRole.eq("user_id", id);
        List<UserRole> userRoles = userRoleService.list(queryUserRole);
        List<Long> roles = userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList());
        userVO.setRoles(roles);

        if (CollectionUtils.isNotEmpty(roles)) {
            List<String> collect = new ArrayList<>();
            roles.forEach(item -> {
                TabRole role = roleService.getById(item);
                collect.addAll(Optional.ofNullable(role.getPermissions()).orElse(new ArrayList<>()));
            });
            List<String> permissions = collect.stream().distinct().collect(Collectors.toList());
            userVO.setPermissions(permissions);
        }
        return userVO;
    }

}